/**
 * Copyright (c) 2020 Coder League
 * All rights reserved.
 *
 * File：RoleService.java
 * History:
 *         2020年12月20日: Initially created, Chrise.
 */
package club.coderleague.cfss.service.role;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.validation.ValidationException;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import club.coderleague.cfss.dao.RoleAuthDao;
import club.coderleague.cfss.dao.RoleDao;
import club.coderleague.cfss.domain.beans.PagingParameters;
import club.coderleague.cfss.domain.entities.Roleauths;
import club.coderleague.cfss.domain.entities.Roles;
import club.coderleague.cfss.domain.enums.EntityState;
import club.coderleague.cfss.exceptions.RequestProcessInfoException;
import club.coderleague.data.jpa.domain.Page;

/**
 * 角色服务。
 * @author Chrise
 */
@Service
public class RoleService {
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private RoleAuthDao raDao;
	
	/**
	 * 分页查询角色。
	 * @author Chrise 2020年12月20日
	 * @param pagingparameters 分页参数。
	 * @param isrecycle 是否回收站。
	 * @param keyword 关键字。
	 * @return 分页角色数据。
	 */
	public Page<Roles> findPageByParamsMap(PagingParameters pagingparameters, boolean isrecycle, String keyword) {
		return this.roleDao.findPageByParamsMap(pagingparameters, isrecycle, keyword);
	}
	
	/**
	 * 根据角色主键查询角色。
	 * @author Chrise 2020年12月20日
	 * @param entityid 角色主键。
	 * @return 角色数据。
	 */
	public Map<String, Object> findMapByEntityid(Long entityid) {
		if (entityid == null) {
			throw new ValidationException("角色主键不能为空");
		}
		Map<String, Object> roles = this.roleDao.findMapByEntityid(entityid);
		List<String> funcids = this.raDao.findFuncidByRoleid(entityid);
		roles.put("funcids", funcids != null ? StringUtils.join(funcids, ",") : null);
		return roles;
	}
	
	/**
	 * 新增角色。
	 * @author Chrise 2020年12月20日
	 * @param roles 角色对象。
	 * @param funcids 授权功能。
	 */
	public void insert(Roles roles, String funcids) {
		if (this.roleDao.existsByRolenameNotEntityid(roles.getRolename(), null)) {
			throw new RequestProcessInfoException("角色名称已存在");
		}
		roles.setEntitystate(EntityState.VALID.getValue());
		this.roleDao.save(roles);
		
		if (StringUtils.isNotBlank(funcids)) {
			for (String funcidstr : funcids.split(",")) {
				Long funcid = Long.parseLong(funcidstr);
				this.raDao.save(new Roleauths(EntityState.VALID.getValue(), roles.getEntityid(), funcid));
			}
		}
	}
	
	/**
	 * 更新角色。
	 * @author Chrise 2020年12月20日
	 * @param roles 角色对象。
	 * @param funcids 授权功能。
	 */
	public void update(Roles roles, String funcids) {
		if (this.roleDao.existsByRolenameNotEntityid(roles.getRolename(), roles.getEntityid())) {
			throw new RequestProcessInfoException("角色名称已存在");
		}
		Roles rolesSource = this.roleDao.getOne(roles.getEntityid());
		rolesSource.setRolename(roles.getRolename());
		rolesSource.setRoledesc(roles.getRoledesc());
		
		List<Long> validentityids = new ArrayList<>();
		if (StringUtils.isNotBlank(funcids)) {
			for (String funcidstr : funcids.split(",")) {
				Long funcid = Long.parseLong(funcidstr);
				Roleauths roleauths = this.raDao.findOneByRoleidAndFuncid(roles.getEntityid(), funcid);
				if (roleauths != null) {
					if (EntityState.INVALID.equalsValue(roleauths.getEntitystate())) {
						roleauths.setEntitystate(EntityState.VALID.getValue());
					}
					validentityids.add(roleauths.getEntityid());
				} else {
					roleauths = new Roleauths(EntityState.VALID.getValue(), roles.getEntityid(), funcid);
					this.raDao.save(roleauths);
					validentityids.add(roleauths.getEntityid());
				}
			}
		}
		this.raDao.updateEntitystateByRoleidNotInEntityids(EntityState.INVALID.getValue(), roles.getEntityid(), validentityids);
	}
	
	/**
	 * 更新角色状态。
	 * @author Chrise 2020年12月20日
	 * @param entityids 角色主键。
	 * @param entitystate 实体状态。
	 * @param isdistinct 是否去重。
	 */
	public void updateEntitystate(String entityids, Integer entitystate, boolean isdistinct) {
		if (StringUtils.isBlank(entityids)) {
			throw new ValidationException("角色主键不能为空");
		}
		for (String entityid : entityids.split(",")) {
			Roles roles = this.roleDao.getOne(Long.parseLong(entityid));
			if (roles == null) {
				continue;
			}
			if (isdistinct && this.roleDao.existsByRolenameNotEntityid(roles.getRolename(), roles.getEntityid())) {
				throw new RequestProcessInfoException("角色名称已存在");
			}
			roles.setEntitystate(entitystate);
		}
	}
	
	/**
	 * 根据角色主键查询授权功能。
	 * @author Chrise 2020年12月20日
	 * @param roleid 角色主键。
	 * @return 授权功能。
	 */
	public List<Map<String, Object>> findAuthFunctionsByRoleid(Long roleid) {
		if (roleid == null) {
			throw new ValidationException("角色主键不能为空");
		}
		return this.roleDao.findAuthFunctionsByRoleid(roleid);
	}
}
